package lion.lua;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.ReadTimeoutException;
import lion.netty4.core.MyIoExecutor;
import lion.netty4.core.Netty4Server;
import lion.netty4.filter.MsgValidManger;
import lion.netty4.message.RequestMessageRaw;

public class LuaServerRawHanlder extends SimpleChannelInboundHandler<ByteBuf> {

	private static Logger logger = LoggerFactory.getLogger(LuaServerRawHanlder.class);

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		// logger.info("channel active");
		ctx.channel().attr(Netty4Server.KEY_MSG_VISIT_TIME).set(new MsgValidManger());
		MyIoExecutor.initGamePlayer(ctx.channel());
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		ctx.channel().attr(Netty4Server.KEY_MSG_VISIT_TIME).set(null);
		MyIoExecutor.removeGamePlayer(ctx.channel());
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, ByteBuf reqBuf) throws Exception {
		RequestMessageRaw reqMsg = new RequestMessageRaw(reqBuf);
		int msgCode = reqMsg.getMsgCode();
		logger.info("receive msg,code={}", msgCode);
		// 判断消息发送频率
		MsgValidManger msgValidManger = ctx.channel().attr(Netty4Server.KEY_MSG_VISIT_TIME).get();
		if (msgValidManger == null) {
			logger.error("msg filter fail!session is null");
			return;
		}
		int result = msgValidManger.isValidMsg(msgCode);
		switch (result) {
		case MsgValidManger.OK_Validity:
			MyIoExecutor.executeIoRequest(ctx.channel(), reqMsg);
			break;
		case MsgValidManger.Alert_Validity:
			logger.warn("message is discarded for Frequently! code={},times={},channelId={}", msgCode, result,
					ctx.channel().id());
			// MyIoExecutor.executeIoRequest(ctx.channel(), reqMsg);
			break;
		case MsgValidManger.Frequently_Validity:
			logger.error("message too Frequently,close channel!：code={} result={}", msgCode, result);
			ctx.channel().close();
			break;
		}
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		if (cause instanceof ReadTimeoutException) {
			logger.info("ReadTimeout 5min,remove player,addr={}", ctx.channel().remoteAddress());
		} else {
			logger.info("Unexpected Exception,msg={},type={}", cause.getMessage(), cause.toString());
		}
		ctx.close();
	}

}
